Porting Visual Basic solutions to REALBasic is not really complicated or an impossible task. Actually once you learn the differences between both languages the task will become relatively simple. The REALBasic language is highly compatible with Visual Basic and as you learn more about REALBasic you will find that its very easy to apply your Visual Basic knowledge and skills, not only that but you will be able to use almost all of your code in your new REALBasic application.
This is not an in-depth guide to teach REALBasic but instead a few guidelines and pointers to help you understand how to accomplish certain tasks in REALBasic from the standpoint of a Visual Basic programmer. This guide is a work in progress so please come back to check for new additions to this guide.
Data Types:
This should be the first thing you check. If the variables do not match REALBasic data types the code will never run. VB Project Converter will change a lot of data types to RealBasic data types.
Date:
The date in VB is an intrinsic data type and not a class like in REALBasic. Therefore in REALBasic you must create a new instance of a class before using it. Also since its an intrinsic data type you can represent and assign dates literally, as in the following example:
Dim D as date
D = #122501#
The above would be like this in REALBasic:
Dim D as date
D = new date
Dim x as boolean
x = parseDate(122501,d)
Notice that we create a new instance of Date using the NEW statement. You could also create a new instance in the DIM statement like this:
Dim D as new date
In VB the date data type is an actual double. Since it is a numeric data type we can manipulate date mathematically. In REALBasic we can achieve a similar functionality using the totalofseconds property. See the Online Reference for more information on the date class.
It may seem like an unnecessary overhead, but the fact that date is a class will pay off later when manipulating the date.
Intrinsic Global Objects
There are a few objects in VB, which are available in REALBasic yet VB creates a global intrinsic object instance automatically. In REALBasic the user must create a variable and a new instance for that object. For example the Clipboard is a global object created by VB. In REALBasic the clipboard is a class and we must create a variable of type clipboard and a new instance whenever we access the clipboard.
Variants
If you are using a version of REALBasic prior to 4.0 then you must check your variants. In VB you can use a variant directly like in the following sample.
Dim v as variant
v = 5
msgbox v
Yet in a version of REALBasic prior to 4.0 you must cast the variant before using it. Therefore the above code becomes:
Dim v as variant, i as integer
v = 5
i = v
msgbox str(i)
Type Structures
VB Project Converter will create a class from a type structure. You can use the class like you would use the type structure with one important difference. A type structure is an implicit data type just like strings and integers. When you declare a variable of a type structure you can use it right away. In REALBasic the structure is converted to a class and that means that you have to create a new instance of the class before you use it or else an error will be raised.
ReDim and Array Dimensions
In VB you can redimension an array usin ReDim in REALBasic you can use ReDim to change the amount of elements only not the dimensions.
Handling Errors:
The most common way to handle runtime errors in VB is using the On Error statement. In REALBasic errors are handled with exceptions. This concept is very similar to those used in JAVA and other languages. An exception is raised whenever an error occurs. In VB when an error occurs it will be handle depending on the On Error statement. An On Error statement may tell VB to ignore the error an continue with the next statement that is the case of statement On Error Resume Next; or tell VB to jump to a specific location in your code when the error occurs this is the case of the statement On Error Goto Label, where label is an the actual name of a label. If no On Error statement is used VB will handle the error itself showing an alert with a generic error description and quitting the application.
In REALBasic just like in VB when an exception statement is not present REALBasic will quit in a similar way with a generic message to the user. In REALBasic you do not tell it how to handle the error. REALBasic will simply raise an exception (error) and is your choice to handle it with an Exception statement or let your program crash. You can read the REALBasic documentation or the online help in the IDE to find out how to implement exceptions; here we will only cover the basics.
Exceptions in REALBasic are placed at the end of a method (sub or function). Due to the object oriented nature of REALBasic, errors are represented by a RuntimeException class. REALBasic defines a series of runtime exceptions like NilObjectException: when you use an object that does not exists, a OutOfBoundsException: when you try to access an array element pass the actual dimensions of the array, and others as described on the online documentation. The exception statement is not part of your regular code, is there to be executed only when an error is raised and therefore you do not have to exit your code before an Exception statement like you have to do with an On Error Goto Label statement. With the Exception statement you opt to catch any exception or a particular type of exceptions. An exception statement that catches any error would be how you implement the On Error Goto Label statement from VB. Notice that in REALBasic you cannot resume after an error once an exception is raised the code will exit and it will return to the calling code. Second you cannot reset or clear an error handling. In REALBasic once you code an exception statement it will apply until the procedure terminates because they have a local scope.
Now these two last observations about REALBasics error handling brings up another interesting fact about runtime errors in REALBasic (better known in the REALBasic world as exceptions) which in fact is not obvious at first and quite interesting if you have never had a chance to use a language with exceptions. The Exception block where you actually put your error handling code is local in scope that is that it will only be executed for errors that are raised inside the particular procedure. Now lets take a look at this quick scenario: A procedure (known in the REALBasic world as methods) named A calls another procedure B that in turns calls a procedure C. The only procedure with an exception block is A. An error is raised in C, which has no error handling. Because the error was not handle in C and the execution of procedure C terminates. We still have a runtime exception in the air, which is in effect. Meaning that when we return to B from C we know have a runtime error in B also. There is no exception block on B, so we exit B and return to A. We have the same conditions in A as we did in B except that this time REALBasic finds an exception block and it will execute this code and then it will exit A. Notice how in A we are handling an error caused somewhere else. You must be cautious for what kind of error you test in a procedure because even when there may not be any code in a procedure that can cause a particular type of exception in REALBasic, it could be the result of a poor coded procedure somewhere else. This is not really a concern if you practice good programming techniques, remember to anticipate failure conditions in your code, test conditions in code, evaluate for nil objects and always include an exception block.
Case statements
Single line case statements are not supported in REALBasic.
Case val1,val2 : statement
Case Else : statement
These must be converted to two line expressions.
For-Next
You may find For Next loops in VB with a loop index as an argument to the Next statement. In REALBasic this index is no used. VB Project Converter will remove the index argument for you.
Functions
In VB a function returns a value to the calling statement by assigning the value to the function name. In REALBasic we use the Return statement to return a value to the calling statement. VB Project Converter will convert all return assignments to Return statements. For example:
Function DoSomethingWithString(s as string) as string
DoSomethingWithString = "Hello " + s
Exit Function
End Function
will be converted to:
Function DoSomethingWithString(s as string) as string
Dim varDoSomethingWithString as string
varDoSomethingWithString = "Hello " + s
Return varDoSomethingWithString
End Function
There is yet another particular situation with return assignments in VB functions. Inside the scope of a VB function the function name can be treated as a variable, thats how VB allows us to return a value by assigning a value to the function. Since the function name is declared as a variable we can treat it as such in code. Lets review the following VB code:
Function DoSomething (s as string) as string
Dim i as integer
For i = len(s) to 1
DoSomething = DoSomething + Mid(s,i,1)
Next i
Exit Function
End Function
The above code is completely valid in VB. VB Project Converter will be able to convert return assignments but it will not be able to convert the use of function names as variables. The resulting converted code will be:
Function DoSomething (s as string) as string
Dim i as integer
Dim varDoSomething as string
For i = len(s) to 1
varDoSomething = DoSomething + Mid(s,i,1)
Next
Return varDoSomething
End Function
Notice how the function name DoSomething is still used as a variable. The above code will raise a compiler error in REALBasic. The code above must be revised to use a variable instead.
Optional Parameters
Implementing optional parameters is quite different in REALBasic. In VB we declare optional parameters using the OPTIONAL keyword:
Sub DoSomething(param1 as string, Optional param2 as string)
The Optional keyword is not available in REALBasic. To accomplish the same we use the following syntax:
Sub DoSomething(param1 as string, param2 as string = "")
In REALBasic we assign a default value to a parameter. This approach behaves somewhat different to Optional parameters in VB. In VB you can query if an optional parameter is available inside the function, while in REALBasic all parameters are available except that parameters that were not used by the calling statement will have the default value. If you need to determine if a parameter was used you can initialize it to a particular value that will never be used by a caller and test for that value.
Another approach will be to overload the method and declare one method for each of the different combinations of parameters.
Calling conventions for parameters
One VB parameters are always passed by reference if the keyword ByVal is not used. In REALBasic you must use the ByRef keyword on any method parameters that changes the parameter passed. If you are using a REALBasic version prior to 5 all variables passed ByRef to a method must have a local scope that is that the variable passed must be defined in the same place you are calling the method with the ByRef parameter. In VB you can pass any variable regardless of its scope just like in REALBasic 5.
Concatenation Character:
In VB the character (operator) & is used to concatenate values into a string. The advantage of the & character is that it will convert (cast) each value to a string when need. For example:
Dim i as integer
Dim s as string
s = "Hola, the value is " & i & " for the variable i"
In REALBasic the + operator must be used. Whenever VB Project Converter finds a & it will be replaced for +. The + operator does not do any conversion. You are responsible to code the conversions. The only problem that you have is when a value concatenated is not an actual string. You must manually fix these instances yourself VB Project Converter does not keep up with the data types of the values being concatenated with the & operator. For example the above example in REALBasic will be coded as follows:
Dim i as integer
Dim s as string
s = "Hola, the value is " + str(i) + " for the variable i"
File I/O:
In VB users have two options they can either use the traditional file I/O methods or the new File System Object introduced with VBA. VBPC currently only supports the traditional methods.
In REALBasic there is no random access only Binary and sequential access. The good news is that REALBasic file I/O methods like everything else in REALBasic is implemented as classes.
In REALBasic files and directories are represented by the FolderItem class. Before you perform any action in a file or folder you must declare and create a folderitem. There are many functions and methods of the folderitem itself that return a folderitem object. But there are three main ways to achieve this.
You can create one with the absolute path using the GETFOLDERITEM( ) function.
Dim MyFile as folderitem
MyFile = getFolderItem("c:\myfolder\myfile.txt)
Notice the above example only works on Windows because the path delimiters and format is not the same in Macintosh. We will see later how to tackle this platform issue.
If getFolderItem does not find a file it will create an empty FolderItem in which case its property exists will be false.
MyFile = getFolderItem("c:\myfolder\myfile.txt)
If MyFile.Exists = false then
Msgbox Is not there I have to create it.
End If
If by any reason getFolderItem or any other function that returns a folderitem fails it will return a NIL folderitem. So you should test every function like the one above for nil.
MyFile = getFolderItem("c:\myfolder\myfile.txt)
If MyFile = nil then
Msgbox Upps an error.
Return
End If
If MyFile.Exists = false then
Msgbox Is not there I have to create it.
End If
The other option is by showing a Open\Save dialog or a Select Folder dialog. REALBasic doesnt have a commondialog control but you can achieve the same with other REALBasic methods. Lets examine the following VB code that uses a CommonDialog control named dlgCommonDialog:
Dim MyFilePath as string
dlgCommonDialog.InitDir=c:\Program Files
dlgCommonDialog.DialogTitle="Select a program file"
dlgCommonDialog.Filter="*.exe"
dlgCommonDialog.CancelError = true
On Error Goto ErroFileCancel
dlgCommonDialog.ShowOpen
MyFilePath = dlgCommonDialog.FileName
Display full path to opened file in an Texbox
resultEdit.text = MyFilePath
ErroFileCancel:
resultEdit.text = "User Cancelled"
In REALBasic we use the OpenDialog and SaveDialog classes. To display an Open Dialog we use the OpenDialog class. The opendialog class is pretty much like the commondialog and its showopen functionality, the only big different is that the OpenDialog is not a control that you can drag to a form.
Dim dlg as OpenDialog
Dim MyFile as FolderItem
dlg=New OpenDialog
dlg.InitialDirectory=GetFolderItem("c:\Program Files")
dlg.Title="Select a program file"
dlg.Filter="execfiles"
MyFile = dlg.ShowModal()
If MyFile <> Nil then
//Display full path to opened file in an EditField
resultEdit.text = dlg.Result.AbsolutePath
Else
resultEdit.text = "User Cancelled"
End if
The savedialog works very similar to the opendialog in fact they are both based on the same class, FolderItemDialog. Review the online documentation to learn more about the save and open dialogs.
On important point about the open and save dialogs in REALBasic is its Filter property. The Filter property tells REALBasic and VB which files to open. In VB the filter property is a free string that describes the extensions of those files you which to open, therefore you can open any file during runtime. In REALBasic you must predefine the file types in your project at design time. (See the Developers Guide on how to add file types to your project.) There are a few reasons for this, including the fact that Macintosh applications require certain resources that describe which files it owns and which it can open. The Filter property of the save and open dialog is the actual name of a file type as defined in your project.
In VB a filter property can define many file types at once. In REALBasic you must create a File Type for each one of these properties.
Text Files (*.txt ) | .txt | RTF Documents (*.rtf) | *rtf
In fact you only have to define more than one file type if you are developing an application that is compatible with MacOS 9 (Classic) file access. In MacOS 9 files have a file Creator and file Type instead of relaying on the file extension. Since REALBasic offers no mechanism to enter multiple file types and creators on a string you have to define on File Type in REALBasic for each file. If you are programming for MacOS X and Windows which relay more on the file extension you can create on File Type in REALBasic with the creator and type set to "????" and add as many extensions as needed.
Once you have a folderitem you can perform any I/O function using the built in methods of the folderitem class. So lets check the different I/O methods found in VB and how we accomplish the same in REALBasic.
- Kill method is equal to MyFile.Delete.
- FileDateTime is equal to either the MyFile.ModificationTime or MyFile.CreationDate. Both of these methods return a DATE object.
- FileLen is equal to MyFile.Length which returns the file size in bytes, 0 if it is a folder.
- MkDir is equal to MyFile.CreateAsFolder.
- RmDir, deleting files and folders is done with MyFile.Delete.
- Name is equal to changing the name property of MyFile like this MyFile.Name = MyNewName.
- FileCopy is equal to MyFile.CopyFileTo.
Null and Empty
In VB you use Empty to identify a variable that its value has not been initialized. In REALBasic there is no equivalent for Empty. In VB you can assign and test for Empty with any type of variable. In REALBasic you can assign and test for Nil. You can only assign Nil to an object or variant variable.
In VB Null is used to detect if variant contains no valid data. In REALBasic there is the Nil statement, which is used to detect if an object contains valid data. In REALBasic you can only use Nil with objects and variants. Most functions in VB propagate the value of null without causing a runtime error. In REALBasic this is somewhat different. Some functions in REALBasic will take a nil value and return a nil value without problem. For example:
dim s as variant
s = nil
s = left(s,4)
The above REALBasic snippet will execute without a problem. Not every function in REALBasic behaves the same way. Almost all built in functions in REALBasic handle a variant with a value of Nil. In REALBasic Nil variants are converted to the default value of the intrinsic data type used. A variant is converted to a Nil object when the data type is an object. There is no problem with most intrinsic data types like strings, integers, etc, but objects are another story. If at any time you or any code attempt to use a nil object a NilObjectException will be raised.
Soft Binding
In VB some fucntions returns variables of type form, control, object. In VB we can use these generic classes or base objects as if they were of a more specific type. This is know as soft binding. Let's see the following VB snippet.
Sub Form_Load()
DoSomething Me
End Sub
Sub DoSomething(f as form)
f.MyLabel.caption = "Hello"
End Sub
The actual class form does not have a property MyLabel but VB implements a form of late binding. In REALBasic this is not possible and it will complain because the property MyLabel is not a member of from or in the case of REALBasic the window class. Even more VB will allow you to cast up a class inheritance chain. Lets see what we mean:
Sub Form_Load()
DoSomething Me
End Sub
Sub DoSomething(f as form)
Dim m as MyForm
set m = f
m.MyLabel.caption = "Hello"
End Sub
The above example works like the example before except that this time we have an additional particularity to the way VB handles objects. Form is the base class for MyForm and as such we would consider that MyForm is above the inheritance chain. As we can se VB allows to cast to any class as long as it is in the inheritance chain. The code above will not work in REALBasic and will raise a Type Mismatch exception when we attempt to convert an instance of Form to MyForm.
New and Instantiation
Both VB and REALBasic offer a NEW statement. Together with the DIM statement it can be used to reduce code. There is a subtle difference in the way they behave. Lets see the following VB code:
'Code 1
dim a as SomeObject
set a = new SomeObject
a.DoSomething()
set a = nothing
a.DoSomething()
'Code 2
dim a as new SomeObject
a.DoSomething()
set a = nothing
a.DoSomething()
We see how code in example two makes the syntax simpler. There is a very important difference with the two examples above. The first example will generate an error but the second will work fine. While we think both of these examples do the same thing internally VB handles them different. We expected that Dim-New syntax would create a variable and instantiate the variable at the same time and that is not what happens. Internally VB will not create an instance until we actually use the object. In the first example we explicitly create a variable and instantiate the object on the second line. When we set the object to Nothing we can no longer use it thus raising an error. In the other hand the DIM-NEW syntax will create a new instance whenever we access the object if the object has no instance. Thats how the second example works and the first example raises an error. A lot of programmers have used this behavior to their advantage since it allows them to create an object instance without having to test or handle Nil states.
In REALBasic whenever you an instance becomes NIL regardless of the New syntax used the object remains NIL and a runtime error will be raised if you attempt to use it.
Making the conversion easier
The degree of complexity when converting a VB project to REALBasic depends greatly on the complexity of the project you are porting. There are always a few things that we can keep in mind while in Visual Basic that would make the conversion easier.
Avoid using default properties for controls.
DO NOT Text1 = "hello" DO Text1.text = "hello"
Avoid Variants. When ever is possible declare a variable with its data type instead of a variant. We can declare a variable as a variant implicitly and explicitly. An implicit variant is the one where we do not state a data type. The variant is the default data type in Visual Basic 6. This means that any variable, parameter, or function return type that is not explicitly specified is considered a Variant.
If a function modifies a parameter declare the parameter using ByRef.